<?php
set_include_path("../include;include");
require_once '/util/globals.php';
require_once '/dao/Database.php';
require_once '/model/Group.php';

/**
 * database access class for the price categories
 *
 * @author Thomas Crepain <contact@thomascrepain.be>
 */
class PriceCategoryDAO
{
        const TABLENAME = 'price_category';
        const PARTICIPANT_REGISTRATION_TABLENAME = 'participant_registration';

	/**
	 *
	 *
	 * @var Database
	 */
	private $db;

	/**
	 * Contains the price categy cache
	 *
	 * @var array
	 */
	private $priceCategoryCache = array();

	/**
	 * unique instance of this class
	 * Singleton pattern
	 *
	 * @var Database
	 */
	private static $uniqueInstance;


	/**
	 * constructs the DAO
	 */
	private function __construct()
	{
		// get database
                $this->db = Database::getInstance();
	}

	/**
	 * gets instance of database
	 *
	 * @return PriceCategoryDAO
	 */
	public static function getInstance()
	{
		if(!isset(self::$uniqueInstance))
		{
			self::$uniqueInstance = new self();
		}

		return self::$uniqueInstance;
	}

        /**
	 * Returns the event_id
	 *
	 * @return integer
	 */
	public function getEventIdByPriceCategoryId(integer $priceCategoryId)
	{
		// build cache
		$this->buildCache($priceCategoryId);

		return (integer) $this->priceCategoryCache[$priceCategoryId]['event_id'];
	}

        /**
	 * Returns the group_id
	 *
	 * @return integer
	 */
	public function getGroupIdByPriceCategoryId(integer $priceCategoryId)
	{
		// build cache
		$this->buildCache($priceCategoryId);

		return (integer) $this->priceCategoryCache[$priceCategoryId]['group_id'];
	}


	/**
	 * Returns the name
	 *
	 * @return String
	 */
	public function getNameByPriceCategoryId(integer $priceCategoryId)
	{
		// build cache
		$this->buildCache($priceCategoryId);

		return $this->priceCategoryCache[$priceCategoryId]['name'];
	}

        /**
	 * Returns the description
	 *
	 * @return String
	 */
	public function getDescriptionByPriceCategoryId(integer $priceCategoryId)
	{
		// build cache
		$this->buildCache($priceCategoryId);

		return $this->priceCategoryCache[$priceCategoryId]['description'];
	}

        /**
	 * Returns the cost
	 *
	 * @return double
	 */
	public function getCostByPriceCategoryId(integer $priceCategoryId)
	{
		// build cache
		$this->buildCache($priceCategoryId);

		return (double) $this->priceCategoryCache[$priceCategoryId]['cost'];
	}
	
	/**
	 * Returns the PriceCategory object associated with the given Registration id and Participant id.
         *
	 * @param integer $registrationId The id of the Registration
	 * @param integer $participantId The id of the Participant
	 * @return A PriceCategory object
	 */
	public function getPriceCategoryFor(integer $registrationId, integer $participantId) {
            $priceCategories = array();

            // Get all records for both id's
            $record = (array) $this->db->getRecord("SELECT p.price_category_id, p.event_id, p.group_id, p.name, p.description, p.cost
                                                FROM " . self::PARTICIPANT_REGISTRATION_TABLENAME . " AS pr
                                                INNER JOIN " . self::TABLENAME . " AS p ON pr.price_category_id = p.price_category_id
                                                WHERE pr.participant_id = ? AND pr.registration_id = ?",
                                                array($participantId, $registrationId));

            // Put the record in the optionCache
            $this->priceCategoryCache[$record['price_category_id']] = $record;

            // Make a supplement object from the record
            $event = Event::loadEvent((integer) $record['event_id']);
            $group = Group::loadGroup((integer) $record['group_id']);
            $priceCategory = PriceCategory::createNew($event, $group, $record['name'], $record['description'], (double) $record['cost']);
            $priceCategory->setId((integer) $record['price_category_id']);

            // Return the object
            return $priceCategory;
	}
	
	/**
         * Returns the price categories for an event
         *
         * @param Event $event
         * @return array of PriceCategory objects
         */
        public function getPriceCategoriesFor(Event $event){
            $priceCategories = array();

            // Get all records for both id's
            $records = (array) $this->db->getRecords("SELECT p.price_category_id, p.event_id, p.group_id, p.name, p.description, p.cost
                                                    FROM ".self::TABLENAME." AS p
                                                    WHERE p.event_id = ?",
                                                    array($event->getId()));

            // for every retrieved record...
            foreach ($records as $record) {
                // Put every record in the optionCache
                $this->priceCategoryCache[$record['price_category_id']] = $record;

                // Make a supplement object from every record
                $group = Group::loadGroup((integer) $record['group_id']);
                $priceCategory = PriceCategory::createNew($event, $group, $record['name'], $record['description'], (double) $record['cost']);
                $priceCategory->setId((integer) $record['price_category_id']);
                $priceCategories[] = $priceCategory;
            }

            // Return an array of those supplement objects
            return $priceCategories;
        }


	/**
	 * Build the cache for the priceCategoryId if needed
	 *
	 * @param integer	$priceCategoryId
	 */
	private function buildCache(integer $priceCategoryId)
	{
		// if cache is not build
		if(!isset($this->priceCategoryCache[$priceCategoryId]))
		{
                    // fill cache with this priceCategory
                    $this->priceCategoryCache[$priceCategoryId] = $this->db->getRecord("SELECT p.price_category_id, p.event_id, p.group_id, p.name, p.description, p.cost
                                                                            FROM ".self::TABLENAME." AS p
                                                                            WHERE p.price_category_id = ?",
                                                                            array($priceCategoryId));
		}
	}


        /**
         * Saves the given member in the database
         *
         * @param PriceCategory $priceCategory
         * @return integer $id  id in database
         */
        public function save(PriceCategory $priceCategory){
            $id = 0;

            // is this a new member?
            if(is_null($priceCategory->getId())){
                $id = $this->db->insert(self::TABLENAME, array(
                        'event_id' => $priceCategory->getEvent()->getId(),
                        'group_id' => !is_null($priceCategory->getGroup()->getId()) ?  $priceCategory->getGroup()->getId() : NULL,
                        'name' => $priceCategory->getName(),
                        'description' => $priceCategory->getDescription(),
                        'cost' => $priceCategory->getCost()));
            } else {
                $id = $priceCategory->getId();

                $this->db->update(self::TABLENAME, array(
                        'event_id' => $priceCategory->getEvent()->getId(),
                        'group_id' => !is_null($priceCategory->getGroup()->getId()) ?  $priceCategory->getGroup()->getId() : NULL,
                        'name' => $priceCategory->getName(),
                        'description' => $priceCategory->getDescription(),
                        'cost' => $priceCategory->getCost()));
            }

            return $id;
        }
}

?>